/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.claro.administracionSolicitudes.beans;

import co.com.claro.administracionSolicitudes.dao.exceptions.ClaroException;
import co.com.claro.administracionSolicitudes.db.EJBDatabaseSolicitudesLocal;
import co.com.claro.administracionSolicitudes.entity.Aplicacion;
import co.com.claro.administracionSolicitudes.entity.Gerencia;
import co.com.claro.administracionSolicitudes.entity.TipoAplicacion;
import co.com.claro.administracionSolicitudes.entity.enums.EstadoActividadEnum;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;

/**
 *
 * @author Mike
 */
@ManagedBean
@ViewScoped
public class CrearAplicacionBean {

    @EJB
    private EJBDatabaseSolicitudesLocal localDatabase;

    @ManagedProperty(value = "#{usuarioSessionBean}")
    private UsuarioSessionBean sesionBean;
    /**
     * String que almacena el nombre de la ciudad
     */
    private String nombreAplicacion;
    /**
     * Lista con los posibles tipos de aplicaciones
     */
    private List<Aplicacion> aplicaciones;

    /**
     * Lista de los items para el select one menu
     */
    private List<SelectItem> tipoAplicacionesItems;
    /**
     * Objeto seleccionado del select one menu
     */
    private String tipoAplicacionSeleccionado;
    /**
     * Objeto con la aplicación seleccionada por el usuario
     */
    private Aplicacion aplicacionSeleccionada;
    /**
     * Variable que contiene el mensaje de error o confirmación de la acción
     * realizada por el usuario
     */
    private String mensaje;

    private List<SelectItem> gerenciasAsignadorasItems;

    private String gerenciaAsignadoraSeleccionada;

    private int filas = 15;

    private static final String COL_DEFAULT_SORT = "nombre";
    private static final String COL_TIPO_APLICACION = "tipoAplicacion.nombre";
    private static final String COL_GERENCIA_ASIGNADORA = "gerenciaAsignadora";

    private String columnaSorteada;
    private boolean ascendiente;

    /**
     * Creates a new instance of CrearAplicacionBean
     */
    public CrearAplicacionBean() {
    }

    @PostConstruct
    public void inicializarValores() {

        columnaSorteada = COL_DEFAULT_SORT;
        ascendiente = true;

        obtenerAplicaciones();
        List<TipoAplicacion> tipoAplicaciones = localDatabase.findTipoAplicacionByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (tipoAplicacionesItems == null) {
            tipoAplicacionesItems = new ArrayList<SelectItem>();
        }
        for (TipoAplicacion app : tipoAplicaciones) {
            tipoAplicacionesItems.add(new SelectItem(app.getIdTipoAplicacion(), app.getNombre()));
        }

        List<Gerencia> gerencias = localDatabase.findGerenciaByEstado(EstadoActividadEnum.ACTIVO.getId());

        if (gerenciasAsignadorasItems == null) {
            gerenciasAsignadorasItems = new ArrayList<SelectItem>();
        }
        for (Gerencia gerencia : gerencias) {
            gerenciasAsignadorasItems.add(new SelectItem(gerencia.getIdGerencia(), gerencia.getNombre()));
        }
    }

    //************************** METODOS PROPIOS DEL EJB ************************
    /**
     * Método que envía el objeto al EJB para que se persista en base de datos
     */
    public void crearAplicacion(ActionEvent event) {
        if (isCamposInvalidos()) {
            return;
        }

        Aplicacion aplicacion = new Aplicacion();

        aplicacion.setNombre(nombreAplicacion);
        aplicacion.setTipoAplicacion(new TipoAplicacion(Integer.parseInt(tipoAplicacionSeleccionado)));
        aplicacion.setGerenciaAsignadora(new Gerencia(Short.parseShort(gerenciaAsignadoraSeleccionada)));
        aplicacion.setActivo(EstadoActividadEnum.ACTIVO.getId());
        aplicacion.setUsuario(sesionBean.getUsuario().getUsername());
        try {

            if (localDatabase.countAplicacionByNombreTipoEstado(nombreAplicacion,
                    Integer.parseInt(tipoAplicacionSeleccionado), EstadoActividadEnum.ACTIVO.getId()) == 0) {
                localDatabase.crearAplicacion(aplicacion);
                mensaje = ResourceBundle.getBundle("mensajes").getString("cambiosGuardadosOk");
            } else {
                mensaje = ResourceBundle.getBundle("errores").getString("errorAplicacionRepetida");
            }
        } catch (ClaroException ex) {
            mensaje = ex.getMessage();
        }
        obtenerAplicaciones();
        borrarCampos();
    }

    /**
     * Método que envía el objeto al EJB para que se persista en base de datos
     */
    public void modificarAplicacion(ActionEvent event) {
        if (isCamposInvalidos()) {
            return;
        }

        aplicacionSeleccionada.setNombre(nombreAplicacion);
        aplicacionSeleccionada.setTipoAplicacion(new TipoAplicacion(Integer.parseInt(tipoAplicacionSeleccionado)));
        aplicacionSeleccionada.setGerenciaAsignadora(new Gerencia(Short.parseShort(gerenciaAsignadoraSeleccionada)));
        aplicacionSeleccionada.setUsuario(sesionBean.getUsuario().getUsername());

        try {
            localDatabase.modificarAplicacion(aplicacionSeleccionada);
            mensaje = ResourceBundle.getBundle("mensajes").getString("cambiosGuardadosOk");
        } catch (ClaroException ex) {
            mensaje = ex.getMessage();
            Logger.getLogger(CrearAplicacionBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        obtenerAplicaciones();
        borrarCampos();
    }

    /**
     * Método que envía el objeto al EJB para que se persista en base de datos
     */
    public void eliminarAplicacion(ActionEvent event) {
        aplicacionSeleccionada = obtenerObjeto(event);

        aplicacionSeleccionada.setUsuario(sesionBean.getUsuario().getUsername());
        try {
            localDatabase.borradoLogicoAplicacion(aplicacionSeleccionada);
            mensaje = ResourceBundle.getBundle("mensajes").getString("cambiosGuardadosOk");
        } catch (ClaroException ex) {
            Logger.getLogger(CrearAplicacionBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        obtenerAplicaciones();
        borrarCampos();
    }

    /**
     * Método que obtiene las aplicaciones almacenadas en base de datos
     */
    private void obtenerAplicaciones() {
        aplicaciones = localDatabase.findAplicacionByEstado(EstadoActividadEnum.ACTIVO.getId());
    }

    //**************************** EVENTOS PROPIOS DEL BEAN ********************
    /**
     * Método que obtiene el id del objeto contenido dentro del data table
     *
     * @param ActionEvent, evento para buscar el objeto dentro del contexto
     * @return Object, con el id del objeto
     */
    private Aplicacion obtenerObjeto(ActionEvent event) {
        FacesContext context = FacesContext.getCurrentInstance();
        UIComponent componente = event.getComponent().findComponent("idAplicacionOutputText");
        Integer id = (Integer) componente.getValueExpression("value").getValue(context.getELContext());
        return aplicaciones.get(aplicaciones.indexOf(new Aplicacion(id)));
    }

    /**
     * Método que obtiene el objeto seleccionado por el usuario
     *
     * @param event
     */
    public void seleccionarAplicacion(ActionEvent event) {
        aplicacionSeleccionada = obtenerObjeto(event);

        nombreAplicacion = aplicacionSeleccionada.getNombre();
        tipoAplicacionSeleccionado = aplicacionSeleccionada.getTipoAplicacion().getIdTipoAplicacion().toString();
        gerenciaAsignadoraSeleccionada = aplicacionSeleccionada.getNombre();
    }

    /**
     * Método que valida todos los campos, incluye el mensaje de error en el
     * contexto y retorna una respuesta dependiendo de los que encuentre en las
     * validaciones
     *
     * @return boolean, indicando si los campos del formulario son correctos o
     * no
     */
    private boolean isCamposInvalidos() {
        if (nombreAplicacion == null || nombreAplicacion.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorNombreAplicacion");
            mensaje = error;
            return true;
        }
        if (tipoAplicacionSeleccionado == null || tipoAplicacionSeleccionado.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorAplicacion");
            mensaje = error;
            return true;
        }
        if (gerenciaAsignadoraSeleccionada == null || gerenciaAsignadoraSeleccionada.isEmpty()) {
            String error = ResourceBundle.getBundle("errores").getString("errorAplicacionNoGerencia");
            mensaje = error;
            return true;
        }
        return false;
    }

    /**
     * Método que borra los campos cuando se han hecho modificaciones
     */
    private void borrarCampos() {
        nombreAplicacion = null;
        tipoAplicacionSeleccionado = null;
        aplicacionSeleccionada = null;

        columnaSorteada = COL_DEFAULT_SORT;
        ascendiente = true;
    }

    public boolean paginado() {
        return aplicaciones.size() > filas;
    }

    public void ordenar() {
        String property = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
                .get("sortProperty");

        if (property != null) {
            if (columnaSorteada.equals(property)) {
                ascendiente = !ascendiente;
            } else {
                columnaSorteada = property;
                ascendiente = true;
            }
        }

        if (columnaSorteada != null && !columnaSorteada.isEmpty()) {
            if (columnaSorteada.equals(COL_DEFAULT_SORT)) {
                if (ascendiente) {
                    Collections.sort(aplicaciones, new Comparator<Aplicacion>() {

                        @Override
                        public int compare(Aplicacion o1, Aplicacion o2) {
                            return o1.getNombre().compareTo(o2.getNombre());
                        }
                    });
                } else {
                    Collections.sort(aplicaciones, new Comparator<Aplicacion>() {

                        @Override
                        public int compare(Aplicacion o1, Aplicacion o2) {
                            return o2.getNombre().compareTo(o1.getNombre());
                        }
                    });
                }
            } else if (columnaSorteada.equals(COL_TIPO_APLICACION)) {
                if (ascendiente) {
                    Collections.sort(aplicaciones, new Comparator<Aplicacion>() {

                        @Override
                        public int compare(Aplicacion o1, Aplicacion o2) {
                            return o1.getTipoAplicacion().getNombre().compareTo(o2.getTipoAplicacion().getNombre());
                        }
                    });
                } else {
                    Collections.sort(aplicaciones, new Comparator<Aplicacion>() {

                        @Override
                        public int compare(Aplicacion o1, Aplicacion o2) {
                            return o2.getTipoAplicacion().getNombre().compareTo(o1.getTipoAplicacion().getNombre());
                        }
                    });
                }
            } else if (columnaSorteada.equals(COL_GERENCIA_ASIGNADORA)) {
                if (ascendiente) {
                    Collections.sort(aplicaciones, new Comparator<Aplicacion>() {

                        @Override
                        public int compare(Aplicacion o1, Aplicacion o2) {
                            return o1.getGerenciaAsignadora().getNombre().compareTo(o2.getGerenciaAsignadora().getNombre());
                        }
                    });
                } else {
                    Collections.sort(aplicaciones, new Comparator<Aplicacion>() {

                        @Override
                        public int compare(Aplicacion o1, Aplicacion o2) {
                            return o2.getGerenciaAsignadora().getNombre().compareTo(o1.getGerenciaAsignadora().getNombre());
                        }
                    });
                }
            }
        }
    }

    //+++++++++++++++++++++++ GETTERS Y SETTERS +++++++++++++++++++++++++++++++++++
    public String getNombreAplicacion() {
        return nombreAplicacion;
    }

    public void setNombreAplicacion(String nombreAplicacion) {
        this.nombreAplicacion = nombreAplicacion;
    }

    public List<Aplicacion> getAplicaciones() {
        return aplicaciones;
    }

    public void setAplicaciones(List<Aplicacion> aplicaciones) {
        this.aplicaciones = aplicaciones;
    }

    public List<SelectItem> getTipoAplicacionesItems() {
        return tipoAplicacionesItems;
    }

    public void setTipoAplicacionesItems(List<SelectItem> tipoAplicacionesItems) {
        this.tipoAplicacionesItems = tipoAplicacionesItems;
    }

    public String getTipoAplicacionSeleccionado() {
        return tipoAplicacionSeleccionado;
    }

    public void setTipoAplicacionSeleccionado(String tipoAplicacionSeleccionado) {
        this.tipoAplicacionSeleccionado = tipoAplicacionSeleccionado;
    }

    public UsuarioSessionBean getSesionBean() {
        return sesionBean;
    }

    public void setSesionBean(UsuarioSessionBean sesionBean) {
        this.sesionBean = sesionBean;
    }

    public String getMensaje() {
        return mensaje;
    }

    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

    public int getFilas() {
        return filas;
    }

    public boolean isAscendiente() {
        return ascendiente;
    }

    public List<SelectItem> getGerenciasAsignadorasItems() {
        return gerenciasAsignadorasItems;
    }

    public void setGerenciasAsignadorasItems(List<SelectItem> gerenciasAsignadorasItems) {
        this.gerenciasAsignadorasItems = gerenciasAsignadorasItems;
    }

    public String getGerenciaAsignadoraSeleccionada() {
        return gerenciaAsignadoraSeleccionada;
    }

    public void setGerenciaAsignadoraSeleccionada(String gerenciaAsignadoraSeleccionada) {
        this.gerenciaAsignadoraSeleccionada = gerenciaAsignadoraSeleccionada;
    }

}
